package com.sora.pipeline.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sora.pipeline.common.api.ApiResponse;
import com.sora.pipeline.domain.*;
import com.sora.pipeline.domain.dto.*;
import com.sora.pipeline.service.*;
import jakarta.validation.Valid;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 缺陷管理控制器
 * 
 * @author system
 * @since 2025-01-20
 */
@RestController
@RequestMapping("/api/defects")
@Validated
public class DefectController {

    @Autowired
    private DefectService defectService;
    
    @Autowired
    private DefectTypeService defectTypeService;
    
    @Autowired
    private DefectLevelService defectLevelService;
    
    @Autowired
    private AttachmentService attachmentService;
    
    @Autowired
    private LineService lineService;
    
    @Autowired
    private MilestoneService milestoneService;
    
    @Autowired
    private UserService userService;

    /**
     * 1. 获取缺陷列表
     * 分页获取缺陷列表，支持搜索和筛选，返回包含类型名和等级名的详细信息
     */
    @GetMapping
    public ApiResponse<IPage<DefectWithDetailsDTO>> getDefects(
            @RequestParam int pageNum,
            @RequestParam int pageSize,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) Integer typeId,
            @RequestParam(required = false) Integer levelId,
            @RequestParam(required = false) Long lineId) {
        
        LambdaQueryWrapper<Defect> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Defect::getDeleted, false);
        
        // 搜索条件
        if (StringUtils.hasText(keyword)) {
            queryWrapper.and(wrapper -> wrapper
                .like(Defect::getCode, keyword)
                .or()
                .like(Defect::getDescription, keyword)
                .or()
                .like(Defect::getLocation, keyword)
            );
        }
        
        // 状态筛选
        if (StringUtils.hasText(status)) {
            queryWrapper.eq(Defect::getStatus, status);
        }
        
        // 类型筛选
        if (typeId != null) {
            queryWrapper.eq(Defect::getTypeId, typeId);
        }
        
        // 等级筛选
        if (levelId != null) {
            queryWrapper.eq(Defect::getLevelId, levelId);
        }
        
        // 线路筛选
        if (lineId != null) {
            queryWrapper.eq(Defect::getLineId, lineId);
        }
        
        queryWrapper.orderByDesc(Defect::getCreatedAt);
        
        IPage<Defect> page = defectService.page(new Page<>(pageNum, pageSize), queryWrapper);
        
        // 转换为包含详细信息的DTO
        IPage<DefectWithDetailsDTO> resultPage = page.convert(defect -> {
            DefectWithDetailsDTO dto = DefectWithDetailsDTO.fromDefect(defect);
            
            // 获取线路信息
            if (defect.getLineId() != null) {
                Line line = lineService.getById(defect.getLineId());
                if (line != null && !line.getDeleted()) {
                    dto.setLineCode(line.getLineCode());
                    dto.setLineName(line.getLineName());
                }
            }
            
            // 获取缺陷类型信息
            if (defect.getTypeId() != null) {
                DefectType defectType = defectTypeService.getById(defect.getTypeId());
                if (defectType != null && defectType.getEnabled()) {
                    dto.setTypeName(defectType.getTypeName());
                }
            }
            
            // 获取缺陷等级信息
            if (defect.getLevelId() != null) {
                DefectLevel defectLevel = defectLevelService.getById(defect.getLevelId());
                if (defectLevel != null && defectLevel.getEnabled()) {
                    dto.setLevelName(defectLevel.getLevelName());
                }
            }
            
            // 获取上报人信息
            if (defect.getReporterId() != null) {
                User reporter = userService.getById(defect.getReporterId());
                if (reporter != null && !reporter.getDeleted()) {
                    dto.setReporterName(reporter.getName());
                    dto.setReporterUsername(reporter.getUsername());
                }
            }
            
            return dto;
        });
        
        return ApiResponse.success(resultPage);
    }

    /**
     * 2. 获取缺陷详情
     * 根据ID获取缺陷详细信息
     */
    @GetMapping("/{id}")
    public ApiResponse<Defect> getDefect(@PathVariable Long id) {
        Defect defect = defectService.getById(id);
        if (defect == null || defect.getDeleted()) {
            return ApiResponse.failure(404, "缺陷不存在");
        }
        return ApiResponse.success(defect);
    }

    /**
     * 3. 创建缺陷
     * 创建新的缺陷记录
     */
    @PostMapping
    public ApiResponse<Defect> createDefect(@Valid @RequestBody DefectRequest request) {
        // 检查线路是否存在
        Line line = lineService.getById(request.getLineId());
        if (line == null || line.getDeleted()) {
            return ApiResponse.failure(404, "线路不存在");
        }
        
        // 检查缺陷类型是否存在
        DefectType defectType = defectTypeService.getById(request.getTypeId());
        if (defectType == null || !defectType.getEnabled()) {
            return ApiResponse.failure(404, "缺陷类型不存在或已禁用");
        }
        
        // 检查缺陷等级是否存在
        DefectLevel defectLevel = defectLevelService.getById(request.getLevelId());
        if (defectLevel == null || !defectLevel.getEnabled()) {
            return ApiResponse.failure(404, "缺陷等级不存在或已禁用");
        }
        
        // 生成缺陷编号
        String code = generateDefectCode();
        
        Defect defect = new Defect();
        BeanUtils.copyProperties(request, defect);
        defect.setCode(code);
        defect.setStatus(StringUtils.hasText(request.getStatus()) ? request.getStatus() : "pending");
        defect.setReportTime(request.getReportTime() != null ? request.getReportTime() : LocalDateTime.now());
        defect.setCreatedAt(LocalDateTime.now());
        defect.setUpdatedAt(LocalDateTime.now());
        defect.setDeleted(false);
        
        defectService.save(defect);
        
        // 保存附件
        if (request.getAttachments() != null && !request.getAttachments().isEmpty()) {
            saveAttachments(defect.getId(), request.getAttachments());
        }
        
        return ApiResponse.success(defect);
    }

    /**
     * 4. 更新缺陷
     * 更新缺陷信息
     */
    @PutMapping("/{id}")
    public ApiResponse<Defect> updateDefect(@PathVariable Long id, @Valid @RequestBody DefectRequest request) {
        Defect defect = defectService.getById(id);
        if (defect == null || defect.getDeleted()) {
            return ApiResponse.failure(404, "缺陷不存在");
        }
        
        // 检查线路是否存在
        Line line = lineService.getById(request.getLineId());
        if (line == null || line.getDeleted()) {
            return ApiResponse.failure(404, "线路不存在");
        }
        
        // 检查缺陷类型是否存在
        DefectType defectType = defectTypeService.getById(request.getTypeId());
        if (defectType == null || !defectType.getEnabled()) {
            return ApiResponse.failure(404, "缺陷类型不存在或已禁用");
        }
        
        // 检查缺陷等级是否存在
        DefectLevel defectLevel = defectLevelService.getById(request.getLevelId());
        if (defectLevel == null || !defectLevel.getEnabled()) {
            return ApiResponse.failure(404, "缺陷等级不存在或已禁用");
        }
        
        BeanUtils.copyProperties(request, defect);
        defect.setUpdatedAt(LocalDateTime.now());
        
        defectService.updateById(defect);
        
        // 更新附件
        if (request.getAttachments() != null) {
            updateAttachments(id, request.getAttachments());
        }
        
        return ApiResponse.success(defect);
    }

    /**
     * 5. 删除缺陷
     * 删除指定缺陷
     */
    @DeleteMapping("/{id}")
    public ApiResponse<Void> deleteDefect(@PathVariable Long id) {
        Defect defect = defectService.getById(id);
        if (defect == null || defect.getDeleted()) {
            return ApiResponse.failure(404, "缺陷不存在");
        }
        
        // 检查是否有关联的整改任务
        // TODO: 这里需要检查关联表，暂时先软删除
        defect.setDeleted(true);
        defect.setUpdatedAt(LocalDateTime.now());
        defectService.updateById(defect);
        
        return ApiResponse.success(null);
    }

    /**
     * 6. 更新缺陷状态
     * 更新缺陷状态
     */
    @PutMapping("/{id}/status")
    public ApiResponse<Void> updateDefectStatus(@PathVariable Long id, @Valid @RequestBody DefectStatusUpdateRequest request) {
        Defect defect = defectService.getById(id);
        if (defect == null || defect.getDeleted()) {
            return ApiResponse.failure(404, "缺陷不存在");
        }
        
        defect.setStatus(request.getStatus());
        defect.setRemarks(request.getRemarks());
        defect.setUpdatedAt(LocalDateTime.now());
        
        defectService.updateById(defect);
        return ApiResponse.success(null);
    }

    /**
     * 7. 批量更新状态
     * 批量更新缺陷状态
     */
    @PostMapping("/batch-status")
    public ApiResponse<Void> batchUpdateStatus(@Valid @RequestBody BatchStatusUpdateRequest request) {
        List<Defect> defects = defectService.listByIds(request.getDefectIds());
        if (defects.isEmpty()) {
            return ApiResponse.failure(404, "没有找到要更新的缺陷");
        }
        
        // 批量更新状态
        defects.forEach(defect -> {
            defect.setStatus(request.getStatus());
            defect.setRemarks(request.getRemarks());
            defect.setUpdatedAt(LocalDateTime.now());
        });
        
        defectService.updateBatchById(defects);
        return ApiResponse.success(null);
    }

    /**
     * 8. 获取缺陷类型列表
     * 获取所有启用的缺陷类型
     */
    @GetMapping("/types")
    public ApiResponse<List<DefectType>> getDefectTypes() {
        LambdaQueryWrapper<DefectType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DefectType::getEnabled, true);
        queryWrapper.orderByAsc(DefectType::getSortOrder);
        
        List<DefectType> types = defectTypeService.list(queryWrapper);
        return ApiResponse.success(types);
    }

    /**
     * 9. 获取缺陷等级列表
     * 获取所有启用的缺陷等级
     */
    @GetMapping("/levels")
    public ApiResponse<List<DefectLevel>> getDefectLevels() {
        LambdaQueryWrapper<DefectLevel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DefectLevel::getEnabled, true);
        queryWrapper.orderByAsc(DefectLevel::getSeverity);
        
        List<DefectLevel> levels = defectLevelService.list(queryWrapper);
        return ApiResponse.success(levels);
    }

    /**
     * 10. 获取缺陷统计信息
     * 获取缺陷统计数据
     */
    @GetMapping("/statistics")
    public ApiResponse<Map<String, Object>> getDefectStatistics() {
        LambdaQueryWrapper<Defect> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Defect::getDeleted, false);
        
        long totalDefects = defectService.count(queryWrapper);
        
        // 按状态统计
        queryWrapper.clear();
        queryWrapper.eq(Defect::getDeleted, false).eq(Defect::getStatus, "pending");
        long pendingCount = defectService.count(queryWrapper);
        
        queryWrapper.clear();
        queryWrapper.eq(Defect::getDeleted, false).eq(Defect::getStatus, "confirmed");
        long confirmedCount = defectService.count(queryWrapper);
        
        queryWrapper.clear();
        queryWrapper.eq(Defect::getDeleted, false).eq(Defect::getStatus, "in_progress");
        long inProgressCount = defectService.count(queryWrapper);
        
        queryWrapper.clear();
        queryWrapper.eq(Defect::getDeleted, false).eq(Defect::getStatus, "completed");
        long completedCount = defectService.count(queryWrapper);
        
        queryWrapper.clear();
        queryWrapper.eq(Defect::getDeleted, false).eq(Defect::getStatus, "closed");
        long closedCount = defectService.count(queryWrapper);
        
        Map<String, Object> statistics = Map.of(
            "totalDefects", totalDefects,
            "pending", pendingCount,
            "confirmed", confirmedCount,
            "inProgress", inProgressCount,
            "completed", completedCount,
            "closed", closedCount
        );
        
        return ApiResponse.success(statistics);
    }

    /**
     * 生成缺陷编号
     */
    private String generateDefectCode() {
        String prefix = "D-" + LocalDateTime.now().getYear() + "-";
        LambdaQueryWrapper<Defect> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(Defect::getCode, prefix)
                   .orderByDesc(Defect::getCode)
                   .last("LIMIT 1");
        
        Defect lastDefect = defectService.getOne(queryWrapper);
        if (lastDefect == null) {
            return prefix + "001";
        }
        
        String lastCode = lastDefect.getCode();
        String numberPart = lastCode.substring(prefix.length());
        int nextNumber = Integer.parseInt(numberPart) + 1;
        return prefix + String.format("%03d", nextNumber);
    }

    /**
     * 保存附件
     */
    private void saveAttachments(Long defectId, List<DefectRequest.AttachmentInfo> attachments) {
        List<Attachment> attachmentList = attachments.stream().map(attachmentInfo -> {
            Attachment attachment = new Attachment();
            attachment.setTargetType("defect");
            attachment.setTargetId(defectId);
            attachment.setFileType(attachmentInfo.getFileType());
            attachment.setFileName(attachmentInfo.getFileName());
            attachment.setFileUrl(attachmentInfo.getFileUrl());
            attachment.setFileSize(attachmentInfo.getFileSize());
            attachment.setCreatedAt(LocalDateTime.now());
            attachment.setDeleted(false);
            return attachment;
        }).collect(Collectors.toList());
        
        attachmentService.saveBatch(attachmentList);
    }

    /**
     * 更新附件
     */
    private void updateAttachments(Long defectId, List<DefectRequest.AttachmentInfo> attachments) {
        // 删除原有附件
        LambdaQueryWrapper<Attachment> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(Attachment::getTargetType, "defect")
                    .eq(Attachment::getTargetId, defectId);
        attachmentService.remove(deleteWrapper);
        
        // 保存新附件
        if (!attachments.isEmpty()) {
            saveAttachments(defectId, attachments);
        }
    }

    /**
     * 批量删除缺陷
     */
    @PostMapping("/batch-delete")
    public ApiResponse<Void> batchDeleteDefects(@Valid @RequestBody BatchDeleteRequest request) {
        List<Defect> defects = defectService.listByIds(request.getIds());
        if (defects.isEmpty()) {
            return ApiResponse.failure(404, "没有找到要删除的缺陷");
        }

        try {
            // 逻辑删除缺陷
            defectService.removeBatchByIds(request.getIds());
            
            // 删除相关附件
            LambdaQueryWrapper<Attachment> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(Attachment::getTargetType, "defect")
                        .in(Attachment::getTargetId, request.getIds());
            attachmentService.remove(deleteWrapper);
            
            return ApiResponse.success(null);
        } catch (Exception e) {
            return ApiResponse.failure(500, "批量删除失败: " + e.getMessage());
        }
    }
}
